package com.sillyhat.learningjdk.thread.lock;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * ReentrantLockTest
 *
 * @author 徐士宽
 * @date 2017/3/8 15:26
 */
public class ReentrantLockTest {

    private Lock lock = new ReentrantLock();
    private Set<Integer> existSet = new HashSet<Integer>();

    private static ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock();
    private static ReentrantReadWriteLock.WriteLock wlock = rwlock.writeLock();
    private static ReentrantReadWriteLock.ReadLock rlock = rwlock.readLock();

    private int sequence = 0;

    public static void main(String[] args) {
        ReentrantLockTest test = new ReentrantLockTest();
//        String [] threadNames = {"Xushikuan","HaHaHa","我是大线程","啦啦啦啦","❀"};
        String [] threadNames = new String[50];
        for (int i = 0; i < 50; i++) {
            threadNames[i] = "Thread-" + (i + 1);
        }
        test.testLock(threadNames);
    }

    public void testLock(String [] threadNames){
        for (String threadSrc : threadNames) {
            Thread thread = new Thread(new LockRunnable(threadSrc));
            thread.start();
        }
    }

    private int getSequence(){
//        Lock lock = new ReentrantLock();//错误
        lock.lock();
        try {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            sequence++;
        } finally {
            lock.unlock();
        }
        return sequence;
    }

    private synchronized void checkSequenceExist(int sequence){
        if(existSet.contains(sequence)){
            System.exit(0);
        }else{
            existSet.add(sequence);
        }
    }

    class LockRunnable implements Runnable{

        private String threadName;

        public LockRunnable(String threadName){
            this.threadName = threadName;
        }

        public void run() {
            for (int i = 0; i < 1000000; i++) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int sequence = getSequence();
                System.out.println(threadName + " get sequence ------->" + sequence);
                checkSequenceExist(sequence);
            }
        }
    }
}
